/*
 * @Author       : Atonidas
 * @LastEditors  : Atonidas
 * @LastEditTime : 2023-10-07 09:59:14
 * @FilePath     : \3.Received\User\Flash\MCU_Flash.c
 * @Description  : 
 */
#include "MCU_FLash.h"

/**
 * @brief  Gets the page of a given address
 * @param  Addr: Address of the FLASH Memory
 * @retval The page of a given address
 */
static uint32_t GetPage(uint32_t Addr)
{
    return (Addr - FLASH_BASE) / FLASH_PAGE_SIZE;
}

uint8_t MCU_Flash_EraseProgram(uint32_t _addr_start, uint32_t _addr_end, unsigned short DataLength, unsigned int *pbuff)
{
    FLASH_EraseInitTypeDef Erase_Init_Struct;
    uint32_t Address = 0, Sector_Error = 0, i = 0;
    uint32_t _FirstPage = 0, _NbOfPages = 0;

    HAL_FLASH_Unlock();
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
    _FirstPage                  = GetPage(FLASH_USER_START_ADDR);
    _NbOfPages                  = GetPage(FLASH_USER_END_ADDR) - _FirstPage + 1;
    Erase_Init_Struct.TypeErase = FLASH_TYPEERASE_PAGES;
    Erase_Init_Struct.Page      = _FirstPage;
    Erase_Init_Struct.NbPages   = _NbOfPages;

    if (HAL_FLASHEx_Erase(&Erase_Init_Struct, &Sector_Error) != HAL_OK) {
        while (1) {
            HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
            HAL_Delay(100);
        }
    }
    Address = FLASH_USER_START_ADDR;

    while (i < DataLength ) {
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, pbuff[i]) == HAL_OK) {
            i++;
            Address = Address + 8; /* increment to next double word*/
        } else {
            while (1) {
                HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
                HAL_Delay(100);
            }
        }
    }
    HAL_FLASH_Lock();
    return 1;
}

unsigned short STMFLASH_ReadfWord(unsigned int faddr)
{
    return *(volatile int *)faddr;
}

void STMFLASH_Read(unsigned int ReadAddr, unsigned int *pBuffer, unsigned short NumToRead)
{
    unsigned short i;
    for (i = 0; i < NumToRead; i++) {
        pBuffer[i] = STMFLASH_ReadfWord(ReadAddr); // 读取2个字节.
        ReadAddr += 8;                             // 偏移2个字节.
    }
}
